package fileexplorer.view;

import fileexplorer.Configuration;
import fileexplorer.model.Directory;
import fileexplorer.model.FileManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Enumeration;

/**
 * Created with IntelliJ IDEA.
 * User: rejeev
 * Date: 4/27/13
 * Time: 4:43 PM
 * To change this template use File | Settings | File Templates.
 */
public class FileTree extends JTree {
    private static final Logger LOGGER = LoggerFactory.getLogger(FileTree.class);
    private MainWindow mainWindow;
    private FileManager fileManager = new FileManager();
    private FileTable fileTable;

    public FileTree(MainWindow window, FileTable table, TreeNode root){
        super(root);
        this.mainWindow = window;
        this.fileTable = table;
        this.setCellRenderer(new DirectoryIconRenderer());
        initialize();
    }

    private void initialize(){
        this.setFont(new Font(Font.MONOSPACED, Font.BOLD, 12));
        this.setRowHeight(20);
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent event) {
                FileTree tree = (FileTree) event.getSource();
                TreePath treePath = tree.getPathForLocation(event.getX(), event.getY());
                int selectedRow = tree.getRowForLocation(event.getX(), event.getY());
                if (selectedRow != -1 && event.getClickCount() == 2) {
                    FileTree.this.expandNode(treePath);
                }
            }
        });
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent event) {
                if(event.getKeyCode() == KeyEvent.VK_ENTER){
                    FileTree tree = (FileTree) event.getSource();
                    TreePath selectionPath = tree.getSelectionPath();
                    DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)selectionPath.getLastPathComponent();
                    FileTree.this.setModel(new DefaultTreeModel(selectedNode));
                }
                if(event.getKeyCode() == KeyEvent.VK_RIGHT || event.getKeyCode() == KeyEvent.VK_KP_RIGHT)
                {
                    TreePath treePath = ((FileTree)event.getSource()).getSelectionPath();
                    DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)treePath.getLastPathComponent();
                    if(selectedNode.isLeaf()){
                        FileTree.this.expandNode(treePath);
                    }
                }
            }
        });
        this.addTreeSelectionListener(new TreeSelectionListener() {
            @Override
            public void valueChanged(TreeSelectionEvent event) {
                TreePath treePath = event.getPath();
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)treePath.getLastPathComponent();
                String selectionPath = ((Directory)selectedNode.getUserObject()).path;
                fileTable.setPath(selectionPath);
                fileTable.displayFiles(selectionPath);
            }
        });
    }

    private void expandNode(TreePath treePath){
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)treePath.getLastPathComponent();
        Directory directory = (Directory)node.getUserObject();
        String path = directory.path;
        Directory d = fileManager.getDirectory(path, Configuration.level);
        DefaultMutableTreeNode newNode = getTree(d);
        Enumeration<DefaultMutableTreeNode> enumeration = newNode.children();
        while (enumeration.hasMoreElements()){
            node.add(enumeration.nextElement());
        }
        this.expandPath(treePath);
    }

    public void postInitialize(){
        DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode)this.getModel().getRoot();
        TreePath treePath = new TreePath(rootNode.getPath());
        this.setSelectionPath(treePath);
    }

    public static DefaultMutableTreeNode getTree(final Directory directory){
        if(directory == null) return null;
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(directory);
        for(Directory d : directory.childDirectories){
            DefaultMutableTreeNode n = getTree(d);
            if(n != null)node.add(n);
        }
        return node;
    }
}
